import React, { Suspense, lazy, useState, useEffect } from 'react'
import styled from 'styled-components'
import { BrowserRouter, Redirect, Route, Switch } from 'react-router-dom'

import Web3ReactManager from '../components/Web3ReactManager'
import Header from '../components/Header'
import Footer from '../components/Footer'
import { Box, Flex, Text } from 'rebass'
import NavigationTabs from '../components/NavigationTabs'
import { isAddress, getAllQueryParams } from '../utils'
// import styled from 'styled-components'
import { ApolloProvider } from 'react-apollo'
import { client } from '../apollo/client'
import Wrapper from '../components/Theme'
import NavHeader from '../components/NavHeader'
import { OverviewPage } from '../pages/OverviewPage'
import { useGlobalData } from '../Data/GlobalData'
import { useUniswapHistory } from '../Data/UniswapHistory'
import { timeframeOptions } from '../constants'
import { useAllExchanges } from '../Data/GetAllExchanges'
import LocalLoader from '../components/LocalLoader'


const Swap = lazy(() => import('./Swap'))
const Send = lazy(() => import('./Send'))
const Pool = lazy(() => import('./Pool'))

const AppWrapper = styled.div`
  display: flex;
  flex-flow: column;
  align-items: flex-start;
`

const HeaderWrapper = styled.div`
  ${({ theme }) => theme.flexRowNoWrap}
  width: 100%;
  justify-content: space-between;
`
const FooterWrapper = styled.div`
  width: 100%;
  min-height: 30px;
  align-self: flex-end;
`

const BodyWrapper = styled.div`
  display: flex;
  flex-direction: column;
  width: 100%;
  justify-content: flex-start;
  align-items: center;
  flex: 1;
  overflow: auto;
`

const Narrow = styled.div`
  max-width: 900px;
 margin-left: auto;
margin-right: auto;
`

const ThemedBackground = styled(Box)`
  position: absolute;
  height: 100px;
  z-index: -1;
  top: 0;
  width: 100vw;
  @media screen and (max-width: 64em) {
    height: 100px;}
  ${props => { console.log("0x23", props); return !props.last; }}
`

const Body = styled.div`
  width: 90%;
  /* margin: 0 1.25rem 1.25rem 1.25rem; */
`
function objSlice(obj, lastExclusive) {
  var filteredKeys = Object.keys(obj).slice(0, lastExclusive);
  var newObj = {};
  filteredKeys.forEach(function(key) {
    newObj[key] = obj[key];
  });
  return newObj;
}

export default function App() {
  const [historyDaysToQuery, setHistoryDaysToQuery] = useState(timeframeOptions[4].value)

  // the window to aggregate accross
  const [timeWindow, setTimeWindow] = useState('weekly')

  // currency across site can be USD or ETH
  const [currencyUnit, setCurrencyUnit] = useState('USD')

  const [isOverview, hideOverview] = useState("visible")

  // historical data for chart on overview page
  const [uniswapHistory, monthlyHistory, weeklyHistory] = useUniswapHistory(historyDaysToQuery)

  // data for Uniswap totals on overview page, may be dependent on values in the future
  const globalData = useGlobalData()
  // console.log("dbg globalData is", globalData);
  // console.log("dbg uniswap history is", uniswapHistory);

  // essential data for each exchange above liqudiity threshold
  // DBG Just retrieve 5 for dev
  const exchanges = useAllExchanges();

  //used for route loading
  const [length, setLength] = useState(0)

  const [tokenToExchangeMap, setTokenToExchangeMap] = useState()

  useEffect(() => {
    if (exchanges) {
      setLength(Object.keys(exchanges).length)
    }
    let newSet = {}
    Object.keys(exchanges).map(key => {
      newSet[exchanges[key].tokenAddress.toLowerCase()] = key
      return true
    })
    setTokenToExchangeMap(newSet)
  }, [exchanges])
  const params = getAllQueryParams()
  return (
    <>
      <ApolloProvider client={client}>
        {globalData && uniswapHistory && length ? (
          <Suspense fallback={null}>
            <Wrapper>
              <AppWrapper>
                <HeaderWrapper>
                  <Header
                    currencyUnit={currencyUnit}
                    setCurrencyUnit={setCurrencyUnit}
                  />
                </HeaderWrapper>
                <BodyWrapper>
                  <Body>
                    <Web3ReactManager>
                      <BrowserRouter>
                        <Narrow>
                          <NavigationTabs />
                          {/* this Suspense is for route code-splitting */}
                          <Suspense fallback={null}>
                            <Switch>
                              <Route exact strict path="/swap" component={() =>
                                <Swap hideOverview={hideOverview} currencyUnit={currencyUnit} setCurrencyUnit={setCurrencyUnit} params={params} />
                              } />
                              <Route
                                exact
                                strict
                                path="/swap/:tokenAddress?"
                                render={({ match, location }) => {
                                  if (isAddress(match.params.tokenAddress)) {
                                    return (

                                      <Swap
                                        hideOverview={hideOverview}
                                        currencyUnit={currencyUnit}
                                        setCurrencyUnit={setCurrencyUnit}
                                        location={location}
                                        initialCurrency={isAddress(match.params.tokenAddress)}
                                        params={params}
                                      />

                                    )
                                  } else {
                                    return <Redirect to={{ pathname: '/swap' }} />
                                  }
                                }}
                              />
                              <Route exact strict path="/send" component={() => <Send params={params} />} />
                              <Route
                                exact
                                strict
                                path="/send/:tokenAddress?"
                                render={({ match }) => {
                                  if (isAddress(match.params.tokenAddress)) {
                                    return <Send initialCurrency={isAddress(match.params.tokenAddress)} params={params} />
                                  } else {
                                    return <Redirect to={{ pathname: '/send' }} />
                                  }
                                }}
                              />
                              <Route
                                path={[
                                  '/add-liquidity',
                                  '/remove-liquidity',
                                  '/create-exchange',
                                  '/create-exchange/:tokenAddress?'
                                ]}
                                component={() => <Pool params={params} />}
                              />
                              <Redirect to="/swap" />
                            </Switch>
                          </Suspense>
                        </Narrow>
                        <OverviewPage
                          noChart={(isOverview == "hidden")}
                          currencyUnit={currencyUnit}
                          globalData={globalData}
                          uniswapHistory={uniswapHistory}
                          monthlyHistory={monthlyHistory}
                          weeklyHistory={weeklyHistory}
                          timeWindow={timeWindow}
                          setTimeWindow={setTimeWindow}
                          historyDaysToQuery={historyDaysToQuery}
                          updateTimeframe={setHistoryDaysToQuery}
                        />
                      </BrowserRouter>
                    </Web3ReactManager>
                  </Body>
                </BodyWrapper>
                <FooterWrapper>
                  <Footer />
                </FooterWrapper>
              </AppWrapper>
            </Wrapper>
          </Suspense>
        )
          :

          (
            <LocalLoader fill="true" />
          )}
      </ApolloProvider>
    </>
  )
}
